/**    
 * @Description:博客园地址：https://www.cnblogs.com/zumengjie/      
 * @author:顶风少年   
 * @date:   2021年4月1日 下午10:55:40
 */
package datang.dtdb.session;

import java.util.HashMap;
import java.util.concurrent.ExecutionException;

import datang.dtdb.exceptions.ExecutorException;
import datang.dtdb.executor.Executor;
import datang.dtdb.executor.RowBounds;
import datang.dtdb.executor.SimpleExecutor;
import datang.dtdb.executor.parameter.ParameterHandler;
import datang.dtdb.executor.resultset.DefaultResultSetHandler;
import datang.dtdb.executor.resultset.ResultSetHandler;
import datang.dtdb.executor.statement.CallableStatementHandler;
import datang.dtdb.executor.statement.PreparedStatementHandler;
import datang.dtdb.executor.statement.SimpleStatementHandler;
import datang.dtdb.executor.statement.StatementHandler;
import datang.dtdb.mapping.BoundSql;
import datang.dtdb.mapping.Environment;
import datang.dtdb.mapping.MappedStatement;
import datang.dtdb.mapping.StatementType;
import datang.dtdb.reflection.MetaObject;
import datang.dtdb.scripting.defaults.DefaultParameterHandler;
import datang.dtdb.transaction.Transaction;
import datang.dtdb.type.TypeAilasRegistry;

/**
 * 全局配置类，SqlMapConfig中的内容都会解析到此类
 */
public class Configuration {

	/**
	 * 数据源运行环境
	 */
	private Environment environment;

	/**
	 * 类型转换器
	 */
	private TypeAilasRegistry typeAilasRegistry = new TypeAilasRegistry();

	/**
	 * statement列表包含CRUD，key由namespace和id组成
	 */
	private HashMap<String, MappedStatement> mappedStatements = new HashMap<String, MappedStatement>();

	/**
	 * 默认executor类型
	 */
	private ExecutorType defaultExecutorType = ExecutorType.SIMPLE;

	/**
	 * 根据id获取Statement，由namespace和id组成
	 */
	public MappedStatement getMappedStatement(String id) {
		return mappedStatements.get(id);
	}

	/**
	 * 获取指定的Statement
	 */
	public void addMappedStatement(String id, MappedStatement mappedStatement) {
		mappedStatements.put(id, mappedStatement);
	}

	/**
	 * 获取数据源运行环境
	 */
	public Environment getEnvironment() {
		return environment;
	}

	/**
	 * 设置数据源运行环境
	 */
	public void setEnvironment(Environment environment) {
		this.environment = environment;
	}

	/**
	 * 获取类型别名转换器
	 */
	public TypeAilasRegistry getTypeAilasRegistry() {
		return typeAilasRegistry;
	}

	/**
	 * 获取默认的执行器类型
	 */
	public ExecutorType getDefaultExecutorType() {
		return this.defaultExecutorType;
	}

	/**
	 * 创建ResultSetHandler
	 */
	public ResultSetHandler newResultSetHandler() {
		ResultSetHandler resultSetHandler = new DefaultResultSetHandler();
		return resultSetHandler;
	}

	/**
	 * 创建ParameterHandler
	 * @param mappedStatement 
	 */

	public ParameterHandler newParameterHandler(MappedStatement mappedStatement) {
		ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement);
		return parameterHandler;
	}

	/**
	 * 创建StatementHandler
	 */
	public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter,
			RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
		StatementHandler statementHandler;
		StatementType statementType = mappedStatement.getStatementType();
		switch (statementType) {
		case STATEMENT:
			statementHandler = new SimpleStatementHandler(executor, mappedStatement, parameter, rowBounds,
					resultHandler, boundSql);
			break;
		case PREPARED:
			statementHandler = new PreparedStatementHandler(executor, mappedStatement, parameter, rowBounds,
					resultHandler, boundSql);
			break;
		case CALLABLE:
			statementHandler = new CallableStatementHandler(executor, mappedStatement, parameter, rowBounds,
					resultHandler, boundSql);
			break;
		default:
			throw new ExecutorException(statementType + "没有找到匹配的statementHandler");
		}
		return statementHandler;
	}

	/**
	 * 创建Execute
	 */
	public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
		Executor executor;
		// TODO 此处可以有多种类型，也可以有二级缓存类型
		executor = new SimpleExecutor(this, transaction);
		return executor;
	}

	
	/**
	 * 属性解析器
	 * */
	public MetaObject newMetaObject(Object parameter) {
		return new MetaObject(parameter);
	}

}
